package com.zhdl.modules.common;

import cn.hutool.json.JSONUtil;
import com.project.network.entity.PortComm;
import com.project.network.entity.PortSocket;
import com.zhdl.common.util.WebResult;
import com.zhdl.modules.common.formula.entity.Formula;
import com.zhdl.modules.common.formula.service.FormulaService;
import com.zhdl.modules.common.formula.web.req.FormulaReq;
import com.zhdl.modules.common.logging.entity.OptRecord;
import com.zhdl.modules.common.logging.service.OptRecordService;
import com.zhdl.modules.common.logging.web.req.OptRecordListRequest;
import com.zhdl.modules.common.logging.web.req.OptRecordReq;
import com.zhdl.modules.common.logging.web.resp.OptRecordListResp;
import com.zhdl.modules.common.production.entity.ProductionRecord;
import com.zhdl.modules.common.production.service.ProductionRecordService;
import com.zhdl.modules.common.production.service.dto.ProductionReocrdQueryCriteria;
import com.zhdl.modules.common.production.web.request.ProductionRecordReq;
import com.zhdl.modules.common.production.web.request.ProductionStatisticsReq;
import com.zhdl.modules.common.production.web.response.ProductionStatisticsResp;
import com.zhdl.modules.common.protocol_param.service.ProtocolParamService;
import com.zhdl.modules.common.protocol_param.web.request.ProtocolCommReq;
import com.zhdl.modules.common.protocol_param.web.request.ProtocolSocketReq;
import com.zhdl.modules.common.warn.entity.WarnRecords;
import com.zhdl.modules.common.warn.service.WarnRecordsService;
import com.zhdl.modules.common.warn.service.dto.WarnRecordsQueryCriteria;
import com.zhdl.modules.common.warn.web.request.WarnSelectRequest;
import com.zhdl.modules.system.entity.CustomerUser;
import com.zhdl.modules.system.service.CustomerUserService;
import com.zhdl.modules.system.web.request.UserLoginRequest;
import com.zhdl.modules.system.web.request.UserSelectRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.zhdl.modules.common.production.service.impl.ProductionRecordServiceImpl.*;

@Slf4j
@RestController
@RequestMapping(path = "/api/item", produces = MediaType.APPLICATION_JSON_VALUE)
public class ApiDemoController {

    //系统-用户
    @Resource
    private CustomerUserService customerUserService;
    //系统-协议相关
    @Resource
    private ProtocolParamService protocolParamService;
    //系统-日志
    @Resource
    private OptRecordService optRecordService;
    //系统-报警
    @Resource
    private WarnRecordsService warnRecordsService;
    //项目-产量
    @Resource
    private ProductionRecordService productionRecordService;

    /**
     * 测试接口
     *
     * @return 测试服务是否启动
     */
    @GetMapping("/demo")
    public WebResult<String> InterfaceDebugging() {
        return WebResult.okResult("当前接口通讯正常");
    }

    /**
     * 用户登陆
     *
     * @param login 登陆信息
     * @return 用户信息/登陆提示
     */
    @PostMapping("/login")
    public WebResult<String> userLogin(@RequestBody UserLoginRequest login) {
        //判断是否为游客状态
        if (login.isTourist()) {
            CustomerUser customerUserByUserName = customerUserService.findCustomerUserByUserName(login.getUsername());
            if (customerUserByUserName != null) {
                if (customerUserByUserName.getPassword().equals(login.getPassword())) {
                    String jsonStr = JSONUtil.toJsonStr(customerUserByUserName);
                    return WebResult.okResult(jsonStr);
                } else {
                    return WebResult.okResult("密码错误，请确认后输入");
                }
            } else {
                return WebResult.okResult("用户名错误，请确认后输入");
            }
        } else {
            CustomerUser customerUser = new CustomerUser();
            customerUser.setId("9999");
            customerUser.setUsername("SimulatedAccount");
            customerUser.setPassword("20240618");
            customerUser.setRealName("用户");
            customerUser.setIdentity(0);
            String jsonStr = JSONUtil.toJsonStr(customerUser);
            return WebResult.okResult(jsonStr);
        }
    }

    /**
     * 创建用户
     *
     * @param customerUser 用户创建
     * @return 用户信息
     */
    @PostMapping("/user/insertCustomerUser")
    public WebResult<CustomerUser> insertCustomerUser(@RequestBody CustomerUser customerUser) {
        CustomerUser insert = customerUserService.insert(customerUser);
        return WebResult.okResult(insert);
    }

    /**
     * 更新用户信息
     *
     * @param customerUser 用户更新
     * @return 更新后的用户信息
     */
    @PostMapping("/user/updateCustomerUser")
    public WebResult<CustomerUser> updateCustomerUser(@RequestBody CustomerUser customerUser) {
        CustomerUser update = customerUserService.update(customerUser, customerUser.getId());
        return WebResult.okResult(update);
    }

    /**
     * 删除用户信息
     *
     * @param userId 用户Id
     * @return 用户Id
     */
    @PostMapping("/user/deleteCustomerUser")
    public WebResult<String> deleteCustomerUser(@RequestParam String userId) {
        customerUserService.deleteById(userId);
        return WebResult.okResult("删除当前用户信息" + userId);
    }

    /**
     * 查询用户列表
     *
     * @return List<>用户信息</>
     */
    @GetMapping("/user/findAllList")
    public WebResult<List<CustomerUser>> findAllList() {
        List<CustomerUser> customerUsers = customerUserService.selectAll();
        return WebResult.okResult(customerUsers);
    }

    /**
     * 分页查询用户列表
     *
     * @param request 查询条件
     * @return /
     */
    @PostMapping("/user/findAllPage")
    public WebResult<Page<CustomerUser>> findAllByPage(@RequestBody UserSelectRequest request) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createDate");
        Pageable pageable = PageRequest.of(request.getPageNumber(), request.getPageSize(), sort);
        Page<CustomerUser> allPage = customerUserService.findAllPage(request.getQueryCriteria(), pageable);
        return WebResult.okResult(allPage);
    }


    @Resource
    private FormulaService formulaService;

    @PostMapping("/formula/insertFormula")
    public WebResult<Formula> insertFormula(@RequestBody Formula formula){
        formulaService.addFormula(formula);
        return WebResult.okResult(new Formula());
    }

    @PostMapping("/formula/updateFormula")
    public WebResult<Formula> updateFormula(@RequestBody Formula formula){
        Formula insert = formulaService.update(formula,formula.getId());
        return WebResult.okResult(insert);
    }

    @PostMapping("/formula/deleteFormula")
    public WebResult<String> deleteFormula(@RequestParam Integer formulaId){
        formulaService.deleteById(formulaId);
        return WebResult.okResult("删除中");
    }

    @GetMapping("/formula/findAllList")
    public WebResult<List<Formula>> findAllFormulaList(){
        List<Formula> formulas = formulaService.selectAll();
        return WebResult.okResult(formulas);
    }

    @PostMapping("/formula/findAllPage")
    public WebResult<Page<Formula>> findAllFormulaPage(@RequestBody FormulaReq request){
        Pageable pageable = PageRequest.of(request.getPageNumber(), request.getPageSize());
        Page<Formula> allPage = formulaService.findAllPage(request.getQueryCriteria(), pageable);
        return WebResult.okResult(allPage);
    }


    /**
     * 新增串口
     *
     * @return /
     */
    @PostMapping("/protocol/insertPortComm")
    public WebResult<PortComm> insertPortComm(@RequestBody PortComm portComm) {
        PortComm portCommResult = protocolParamService.savePortCommDict(portComm);
        return WebResult.okResult(portCommResult);
    }

    /**
     * 更新串口
     *
     * @return /
     */
    @PostMapping("/protocol/updatePortComm")
    public WebResult<PortComm> updatePortComm(@RequestBody PortComm portComm) {
        PortComm portCommResult = protocolParamService.updatePortCommDict(portComm);
        return WebResult.okResult(portCommResult);
    }

    /**
     * 删除串口
     *
     * @param id 串口Id
     * @return /
     */
    @GetMapping("/protocol/deletePortComm")
    public WebResult<String> deletePortComm(@RequestParam String id) {
        protocolParamService.deletePortCommDict(id);
        return WebResult.okResult("删除成功");
    }

    /**
     * 查询所有 串口
     */
    @GetMapping("/protocol/comm/findAllList")
    public WebResult<List<PortComm>> findAllCommList() {
        List<PortComm> allProtocolComm = protocolParamService.findAllProtocolComm();
        return WebResult.okResult(allProtocolComm);
    }

    /**
     * 分页查询串口列表
     *
     * @param request 查询条件
     * @return /
     */
    @PostMapping("/protocol/comm/findAllPage")
    public WebResult<Page<PortComm>> findAllCommByPage(@RequestBody ProtocolCommReq request) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createDate");
        Pageable pageable = PageRequest.of(request.getPageNumber(), request.getPageSize(), sort);
        Page<PortComm> allProtocolCommByCondition = protocolParamService.
                findAllProtocolCommByCondition(request.getQueryCriteria(), pageable);
        return WebResult.okResult(allProtocolCommByCondition);
    }

    /**
     * 新增网口
     *
     * @return /
     */
    @PostMapping("/protocol/insertPortSocket")
    public WebResult<PortSocket> insertPortSocket(@RequestBody PortSocket portSocket) {
        PortSocket portCommResult = protocolParamService.savePortSocketDict(portSocket);
        return WebResult.okResult(portCommResult);
    }

    /**
     * 更新网口
     *
     * @return /
     */
    @PostMapping("/protocol/updatePortSocket")
    public WebResult<PortSocket> updatePortSocket(@RequestBody PortSocket portSocket) {
        PortSocket portSocketResult = protocolParamService.updatePortSocketDict(portSocket);
        return WebResult.okResult(portSocketResult);
    }

    /**
     * 删除网口
     *
     * @param id 网口Id
     * @return /
     */
    @GetMapping("/protocol/deletePortSocket")
    public WebResult<String> deletePortSocket(@RequestParam String id) {
        protocolParamService.deletePortSocketDict(id);
        return WebResult.okResult("删除成功");
    }

    /**
     * 查询所有 网口
     */
    @GetMapping("/protocol/socket/findAllList")
    public WebResult<String> findAllSocketList() {
        protocolParamService.findAllProtocolSocket();
        return WebResult.okResult("删除成功");
    }

    /**
     * 分页查询串口列表
     *
     * @param request 查询条件
     * @return /
     */
    @PostMapping("/protocol/socket/findAllPage")
    public WebResult<Page<PortSocket>> findAllSocketByPage(@RequestBody ProtocolSocketReq request) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createDate");
        Pageable pageable = PageRequest.of(request.getPageNumber(), request.getPageSize(), sort);
        Page<PortSocket> allProtocolSocketByCondition = protocolParamService.
                findAllProtocolSocketByCondition(request.getQueryCriteria(), pageable);
        return WebResult.okResult(allProtocolSocketByCondition);
    }

    /**
     * 分页查询系统日志
     *
     * @param request 查询条件
     * @return /
     */
    @PostMapping("/logging/findAllPage")
    public WebResult<Page<OptRecord>> findAllRecord(@RequestBody @Validated OptRecordReq request) {
        Pageable pageable = PageRequest.of(request.getPageNumber(), request.getPageSize());
        Page<OptRecord> allPage = optRecordService.findAllPage(request.getQueryCriteria(), pageable);
        return WebResult.okResult(allPage);
    }
//    @PostMapping("/logging/findAllPage")
//    public WebResult<Page<OptRecordListResp>> findAllRecord(@RequestBody @Validated OptRecordListRequest request) {
//        Pageable pageable = PageRequest.of(request.getPageNumber(), request.getPageSize());
//        Page<OptRecordListResp> allRecordPage = optRecordService.findAllRecordPage(request, pageable);
//        return WebResult.okResult(allRecordPage);
//    }

    /**
     * 查询所有报警记录
     *
     * @return /
     */
    @GetMapping("/warn/findAllList")
    public WebResult<List<WarnRecords>> findAllWarnRecordsList() {
        List<WarnRecords> allWarnRecords = warnRecordsService.findAllWarnRecords();
        return WebResult.okResult(allWarnRecords);
    }

    @PostMapping("/warn/findAllPage")
    public WebResult<Page<WarnRecords>> findAllWarnRecordsPage(@RequestBody WarnSelectRequest warnSelectRequest) {
        WarnRecordsQueryCriteria warnRecordsQueryCriteria = new WarnRecordsQueryCriteria();
        //待扩展

        Pageable pageable = PageRequest.of(warnSelectRequest.getPageNumber(), warnSelectRequest.getPageSize());
        Page<WarnRecords> allPage = warnRecordsService.findAllPage(warnRecordsQueryCriteria, pageable);
        return WebResult.okResult(allPage);
    }

    /**
     * 查询所有项目产量信息
     *
     * @return /
     */
    @GetMapping("/production/findAllList")
    public WebResult<List<ProductionRecord>> findAllProductionRecordsList() {
        List<ProductionRecord> productionRecords = productionRecordService.selectAll();
        return WebResult.okResult(productionRecords);
    }

    /**
     * 分页查询项目产量信息
     *
     * @param request 请求参数
     * @return /
     */
    @PostMapping("/production/findAllPage")
    public WebResult<Page<ProductionRecord>> findAllProductionRecordsPage(@RequestBody ProductionRecordReq request) {
        ProductionReocrdQueryCriteria queryCriteria = request.getQueryCriteria();
        Sort sort = Sort.by(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(request.getPageNumber(), request.getPageSize(), sort);
        Page<ProductionRecord> allPage = productionRecordService.findAllPage(queryCriteria, pageable);
        return WebResult.okResult(allPage);
    }

    /**
     * 查询项目总产量
     *
     * @param request 型号相关信息
     * @return /
     */
    @PostMapping("/production/formulaCount")
    public WebResult<ProductionStatisticsResp> getProductionStatistics(@RequestBody ProductionStatisticsReq request) {
        LocalDate currentDate = LocalDate.now();    // 获取当前日期
        DateTimeFormatter formatterDay = DateTimeFormatter.ofPattern("yyyy-MM-dd");    // 定义日期格式
        DateTimeFormatter formatterMonth = DateTimeFormatter.ofPattern("yyyy-MM");    // 定义日期格式
        DateTimeFormatter formatterYear = DateTimeFormatter.ofPattern("yyyy");    // 定义日期格式
        String today = currentDate.format(formatterDay);   // 格式化当前日期为字符串
        String month = currentDate.format(formatterMonth);
        String year = currentDate.format(formatterYear);
        int quarter = (currentDate.getMonthValue() - 1) / 3 + 1;    //获取当前季度
        String[] fullQuarter = getMonthsInQuarter(year, quarter); //获取全部季度月份

        List<Integer> formulaIds = new ArrayList<>();//获取套餐的Id
        formulaIds.add(request.getFormulaId());
        ProductionReocrdQueryCriteria queryCriteria = new ProductionReocrdQueryCriteria();//查询条件
        queryCriteria.setFormulaId(formulaIds);
        ProductionStatisticsResp resp = new ProductionStatisticsResp();
        resp.setFormulaId(formulaIds.get(0));

        List<ProductionRecord> list = productionRecordService.findList(queryCriteria);
        Map<String, Integer> productionByTime = getProductionByTime(list);
        Integer nowMonth = productionByTime.get(month);
        Integer quarterList1 = productionByTime.get(fullQuarter[0]);
        Integer quarterList2 = productionByTime.get(fullQuarter[1]);
        Integer quarterList3 = productionByTime.get(fullQuarter[2]);
        Integer quarterList = quarterList1 + quarterList2 + quarterList3;
        int nowYear = 0;
        for (String s : productionByTime.keySet()) {
            Integer i = productionByTime.get(s);
            nowYear = nowYear + i;
        }
        queryCriteria.setCreateDate(today);
        List<ProductionRecord> todayList = productionRecordService.findList(queryCriteria);
        int nowToday = 0;
        for (ProductionRecord productionRecord : todayList) {
            nowToday = nowToday + productionRecord.getProductionOutput();
        }

        resp.setDailyProduction(nowToday);
        resp.setMonthlyProduction(nowMonth);
        resp.setQuarterlyProduction(quarterList);
        resp.setAnnualOutput(nowYear);
        resp.setTotalOutput(getProductionByAll(list));
        return WebResult.okResult(resp);
    }


}
